package lab_16.com.acme.bankapp.server;

import java.io.*;
import java.net.*;

import lab_16.com.acme.bankapp.domain.bank.*;
import lab_16.com.acme.bankapp.domain.bank.Exceptions.DataFileLoadingException;
import lab_16.com.acme.bankapp.service.bank.BankDataLoaderService;

public class BankServer {

	ServerSocket providerSocket;
	Socket connection = null;
	ObjectOutputStream out;
	ObjectInputStream in;
	String message;
	Bank bank;

	public BankServer(Bank bank) {
		this.bank = bank;
	}

	enum Mode {
		NONE, ADD
	}

	public void run() {
		Mode mode = Mode.NONE;
		try {
			// 1. creating a server socket
			providerSocket = new ServerSocket(2004, 10);
			// 2. Wait for connection
			System.out.println("Waiting for connection");
			connection = providerSocket.accept();
			System.out.println("Connection received from " + connection.getInetAddress().getHostName());
			// 3. get Input and Output streams
			out = new ObjectOutputStream(connection.getOutputStream());
			out.flush();
			in = new ObjectInputStream(connection.getInputStream());
			sendMessage("Connection successful");
			// 4. The two parts communicate via the input and output streams
			DO_cycle: do {
				try {
					message = (String) in.readObject();
					System.out.println("client>" + message);

					if (mode == Mode.ADD) {
						mode = Mode.NONE;
						try {
							BankDataLoaderService.updateBankFromStringFeed(bank, message);
							sendMessage("Data has been added to the bank.");
						} catch (DataFileLoadingException e) {
							sendMessage("WrongData");
						}
						continue;
					}

					switch (message) {

					case "exit":
						sendMessage("Bye!");
						break DO_cycle;

					case "printbank":
						sendMessage(bank.toString());
						break;

					case "add":
						sendMessage("You have entered adding mode. Please, send the data feed.");
						mode = Mode.ADD;
						break;

					default:
						sendMessage("Command is not supported");

					}

				} catch (ClassNotFoundException classnot) {
					System.err.println("Data received in unknown format");
				}
			} while (!message.equals("exit"));
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 4: Closing connection
			try {
				try {
					in.close();
				} finally {
					try {
						out.close();
					} finally {
						providerSocket.close();
					}
				}

			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	void sendMessage(final String msg) {
		try {
			out.writeObject(msg);
			out.flush();
			System.out.println("server>" + msg);
		} catch (IOException ioException) {
			ioException.printStackTrace();
		}
	}
}
